package com.abl.core.common.ws.handler;

import com.abl.core.common.util.FileKit;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Enumeration;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 处理二进制流
 */
@Slf4j
@Component
@ChannelHandler.Sharable
public class BinaryHandler extends SimpleChannelInboundHandler<BinaryWebSocketFrame> {

    //用于记录和管理所有客户端的channle
    public static ConcurrentHashMap<String, Channel> channelAll = new ConcurrentHashMap<>();

    private static final byte[] DELIMITER = new byte[]{0x1E}; // 分隔符，可以根据需要进行调整


    @Override
    protected void channelRead0(ChannelHandlerContext ctx, BinaryWebSocketFrame msg) throws Exception {
//        log.info("BinaryWebSocketFrame ==>{}", frame);
        log.info("服务器接收到二进制消息,消息长度:[{}]", msg.content().capacity());
        ByteBuf byteBuf = Unpooled.directBuffer(msg.content().capacity());
        log.info("服务器接收到二进制消息,消息byteBuf:{}", byteBuf);

        byteBuf.writeBytes(msg.content());

        //         获取二进制数据
//        ByteBuf byteBuf = frame.content();
//        log.info("BinaryWebSocketFrame byteBuf ==>{}", byteBuf);

//        byte[] binaryData = new byte[byteBuf.readableBytes()];
//        byteBuf.readBytes(binaryData);
//        log.info("BinaryWebSocketFrame binaryData ==>{}", byteBuf);

        //解析二进制数据和额外参数信息
//        int delimiterIndex = findDelimiterIndex(binaryData);
//        byte[] extraInfoBytes = new byte[binaryData.length];
//        System.arraycopy(binaryData, 0, extraInfoBytes, 0, extraInfoBytes.length);
//        log.info("BinaryWebSocketFrame binaryData ==>{}", binaryData);
//        log.info("BinaryWebSocketFrame extraInfoBytes ==>{}", extraInfoBytes);


//        log.info("额外参数 ==>{}", extraInfo);
//
//        byte[] realBinaryData = new byte[delimiterIndex];
//        System.arraycopy(binaryData, 0, realBinaryData, 0, realBinaryData.length);
//        log.info("二进制数据 ==>{}", realBinaryData);

//         处理二进制数据和额外参数信息
//        processBinaryData(realBinaryData);

//        processExtraInfo(extraInfo);

//         响应客户端
//        直接发给所有人
//        ByteBuf byteBuf = Unpooled.directBuffer(capacity);
//        byteBuf.writeBytes(content);
        Enumeration<String> keys = channelAll.keys();
        Iterator<String> iterator = keys.asIterator();
        while (iterator.hasNext()) {
            String channelKey = iterator.next();
            Channel channel = channelAll.get(channelKey);
            channel.writeAndFlush(new BinaryWebSocketFrame(byteBuf));
//            channel.writeAndFlush(new BinaryWebSocketFrame(Unpooled.wrappedBuffer(binaryData)));
//            channel.writeAndFlush(new BinaryWebSocketFrame(realBinaryData));
        }


//        发给所有参会人员


    }

    private void processExtraInfo(String extraInfo) {
        log.error("额外参数信息 {}", extraInfo);
    }

    private void processBinaryData(byte[] realBinaryData) {
        String path = FileKit.saveLocal(realBinaryData, "/file.mp3");
        log.error("二进制数据文件保存位置 {}", path);
    }

    /**
     * 连接成功回调
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        log.info("连接成功--->" + ctx.name());
        channelAll.put(ctx.channel().id().asLongText(), ctx.channel());
    }

    /**
     * 连接被移除后 回调
     */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        log.info("连接被移除--->" + ctx.name());
        channelAll.remove(ctx.channel().id().asLongText());
    }

    /**
     * 连接异常回调
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.info("发生异常之后关闭连接（关闭channel），随后从ChannelGroup中移除--->" + ctx.name());
        cause.printStackTrace();
        channelAll.remove(ctx.channel().id().asLongText());
        ctx.channel().close();
    }

    private int findDelimiterIndex(byte[] binaryData) {
        for (int i = 0; i < binaryData.length; i++) {
            byte b = DELIMITER[0];
            if (binaryData[i] == b) {
                return i;
            }
        }
        return -1;
    }
}
